/* @(#)GcgHelper.java
** 
** Copyright (C) 2012 by Steven D. Stamps
**
**             Trademarks & Copyrights
** Flywheel Management Science(TM), Flywheel Management Model(TM),
** Flywheel Story Editor(TM) and FlywheelMS(TM) are exclusive trademarks
** of Steven D. Stamps and may only be used freely for the purpose of
** identifying the unforked version of this software.  Subsequent forks
** may not use these trademarks.  All other rights are reserved.
**
** DecKanGL (Decorated Kanban Glyph Language) and TribKn (Tribal Knowledge)
** are also exclusive trademarks of Steven D. Stamps.  These may be used
** freely within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** gConGUI (game Controller Graphical User Interface) is an exclusive
** trademark of Steven D. Stamps.  This trademark may be used freely
** within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** Trademark information is available at
** <http://www.flywheelms.com/trademarks>
**
** Flywheel Management Science(TM) is a copyrighted body of management
** metaphors, governance processes, and leadership techniques that is
** owned by Steven D. Stamps.  These copyrighted materials may be freely
** used, without alteration, by the community (users and developers)
** surrounding this GPL3-licensed software.  Additional copyright
** information is available at <http://www.flywheelms.org/copyrights>
**
**              GPL3 Software License
** This program is free software: you can use it, redistribute it and/or
** modify it under the terms of the GNU General Public License, version 3,
** as published by the Free Software Foundation. This program is distributed
** in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
** even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE.  See the GNU General Public License for more details. You should
** have received a copy of the GNU General Public License, in a file named
** COPYING, along with this program.  If you cannot find your copy, see
** <http://www.gnu.org/licenses/gpl-3.0.html>.
*/

package com.flywheelms.library.gcg.helper;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.res.Configuration;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.Toast;

import com.flywheelms.library.FmsLibraryApplication;
import com.flywheelms.library.gcg.enumerator.GcgDialogType;
import com.flywheelms.library.gcg.interfaces.GcgFlingController;
import com.flywheelms.library.gcg.listeners.GcgFlingableListener;

public class GcgHelper {
	
	private static MotionEvent genericMotionEventActionUp;
	private static GcgHelper singleton = null;
	private static int touchSlop = 0;
	private static int minimumTouchVelocity = 0;
	public static final String gesture__FLING_RIGHT = "FlingRight";
	public static final String gesture__FLING_LEFT= "FlingLeft";
	public static final String gesture__FLING_UP= "FlingUp";
	public static final String gesture__FLING_DOWN= "FlingDown";
	public static final String gesture__FLING_NORTH_EAST = "FlingNorthEast";
	public static final String gesture__FLING_NORTH_WEST= "FlingNorthWest";
	public static final String gesture__FLING_SOUTH_EAST= "FlingSouthEast";
	public static final String gesture__FLING_SOUTH_WEST= "FlingSouthWest";
	
	private GcgHelper() {
	}
	
	public static GcgHelper getInstance() {
		if(GcgHelper.singleton == null) {
			GcgHelper.singleton = new GcgHelper();
		}
		return GcgHelper.singleton;
	}
	
	public static int getPixelsForDp(Context aContext, int aDp) {
		DisplayMetrics theDisplayMetrics = new DisplayMetrics();
		((WindowManager) aContext.getSystemService(Context.WINDOW_SERVICE)).
	    	getDefaultDisplay().getMetrics(theDisplayMetrics);
		return (int) (aDp * theDisplayMetrics.density + 0.5);
	}
	
	public static void makeToast(String aString) {
		makeToast(aString, Toast.LENGTH_SHORT, Gravity.CENTER);
	}
	
	public static void makeToast(String aString, int aGravity, int aDuration) {
    	Toast theToast = Toast.makeText(FmsLibraryApplication.getContext(), aString, aDuration);
    	theToast.setGravity(aGravity, 0, 0);
    	theToast.show();
	}
	
	public static MotionEvent getGenericMotionEventActionUp() {
		if(GcgHelper.genericMotionEventActionUp == null) {
			GcgHelper.genericMotionEventActionUp = getGenericMotionEvent(MotionEvent.ACTION_UP);
		}
		return GcgHelper.genericMotionEventActionUp;
	}
		
	private static MotionEvent getGenericMotionEvent(int aMotionEvent) {
		long downTime = SystemClock.uptimeMillis();
		long eventTime = downTime + 100;
		float x = 0.0f;
		float y = 0.0f;
		int metaState = 0;
		MotionEvent motionEvent = MotionEvent.obtain(
		    downTime, 
		    eventTime, 
		    aMotionEvent, 
		    x, 
		    y, 
		    metaState
		);
		return motionEvent;
	}
	
	public void alertDialog(
			Context aContext,
			GcgDialogType aDialogType,
			String aTitle,
			String aMessage) {
		Builder theAlertDialog = new AlertDialog.Builder(aContext);
		theAlertDialog.setTitle(aTitle);
		theAlertDialog.setMessage(aMessage);
		theAlertDialog.setIcon(GcgDialogType.CONFIRMATION.getDrawableResourceId());
//		theAlertDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
//
//		    public void onClick(DialogInterface dialog, int whichButton) {
//		       GuiUtil.makeToast("Yes !");
//		    }});
//		theAlertDialog.setNegativeButton(android.R.string.no, null);
		theAlertDialog.show();
	}

	public static boolean isLandscapeMode() {
		return FmsLibraryApplication.getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
	}

    public static boolean notArrowKeys(int aKeyCode) {
		if(
				aKeyCode==KeyEvent.KEYCODE_DPAD_DOWN ||
				aKeyCode==KeyEvent.KEYCODE_DPAD_UP ||
				aKeyCode==KeyEvent.KEYCODE_DPAD_LEFT ||
				aKeyCode==KeyEvent.KEYCODE_DPAD_RIGHT) {
			return false;
		}
		return true;
	}
    
    public OnTouchListener getFlingTouchListener(Context aContext, GcgFlingController aFlingable) {
    	final GestureDetector theFlingDetector = getFlingDetector(aContext, aFlingable);
    	return new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
		           theFlingDetector.onTouchEvent(event);
		           return true;
			}
		};
    }
    
	public static GestureDetector getFlingDetector(Context aContext, GcgFlingController aFlingable) {
		GestureDetector theFlingDetector =
				new GestureDetector(aContext, new GcgFlingableListener(aFlingable));
		return theFlingDetector;
	}

	public static boolean isHorizontalFlingEvent(MotionEvent aMotionEvent, GcgFlingController aFlingController) {
		if(aMotionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
			aFlingController.setPreviousMotionEventX(aMotionEvent.getX());
			aFlingController.setPreviousMotionEventY(aMotionEvent.getY());
			return false;
		}
		if(aMotionEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
			float theMoveStartX = aFlingController.getPreviousMotionEventX();
			float theMoveEndX= aMotionEvent.getX();
			// HORIZONTAL only
			if(theMoveStartX == theMoveEndX) {
				return false; // just a sloppy tap  ?
			}
			if((theMoveStartX - theMoveEndX) > getTouchSlop() ) {
				return true; // left Fling
			}
			if((theMoveEndX - theMoveStartX) > getTouchSlop() ) {
				return true; // right Fling
			}
		}
		return false;
	}
	
	public static int getTouchSlop() {
		if(GcgHelper.touchSlop == 0) {
		    ViewConfiguration theViewConfiguration = ViewConfiguration.get(FmsLibraryApplication.getContext());
		    GcgHelper.touchSlop = theViewConfiguration.getScaledTouchSlop();
		}
		return GcgHelper.touchSlop;
	}
	
	public static int getMinimumFlingVelocity() {
		if(GcgHelper.minimumTouchVelocity == 0) {
		    ViewConfiguration theViewConfiguration = ViewConfiguration.get(FmsLibraryApplication.getContext());
		    GcgHelper.minimumTouchVelocity = theViewConfiguration.getScaledMinimumFlingVelocity();
		}
		return GcgHelper.minimumTouchVelocity;
	}

	public static int getScreenHeight() {
		DisplayMetrics theDisplayMetrics = FmsLibraryApplication.getContext().getResources().getDisplayMetrics();
		return theDisplayMetrics.heightPixels;
	}

	public static int getScreenWidth() {
		DisplayMetrics theDisplayMetrics = FmsLibraryApplication.getContext().getResources().getDisplayMetrics();
		return theDisplayMetrics.widthPixels;
	}

}
